//  Brett Jones
//  PBR Senior Thesis
//  Copyright Brett Jones October 2007

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Exocortex.Geometry3D;

namespace PBR
{
    public partial class MainForm : Form, IDisposable
    {
        #region Static Variables

        private Color kLightColor = Color.FromArgb(255,255,255,255);
        private Vector3 kLightPos = Vector3.FromXYZ(0.0f, 50.0f, 0.0f);
        private double kViewAngle = 60.0f;
        private string kDefaultPath = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

        private static readonly string kBasePath = "../../data";
        private static readonly string kSavePath = Path.Combine(kBasePath, "result.png");

        #endregion

        #region Member Variables

        // Scene elements
        private Scene scene;
        
        // Tab elements
        public Tab previewerTab;
        public Tab propertiesTab;
        public Tab viewerTab;
        //public Tab layersTab;
        public Tab materialPropertiesTab;
        public Tab materialsPanelTab;
        public Tab strokePropertiesTab;

        public PreviewerControl previewerControl;
        public PBR.Controls.SegmentPropertiesControl segmentPropertiesControl;
        public ViewerControl viewerControl;
        //public LayersControl layersControl;
        public PBR.Controls.MaterialProperties materialProperties;
        public PBR.Controls.MaterialsPanel materialsPanel;
        public PBR.Controls.StrokeProperties strokeProperties;

        private BindingSource propertiesBindingSource;

        #endregion

        #region Member Functions

        /// <summary>
        /// Main Form for the interactive painterly based renderer
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            MyInit();
        }

        public void MyInit()
        {
            // Init Scene Data
            Light light = new Light(kLightColor, kLightPos);
            scene = new Scene(light, kBasePath, mToolStripProgressBar1, mToolStripStatusLabel1, this);

            //propertiesBindingSource = new BindingSource();
            //propertiesBindingSource.DataSource = scene.Renderer.Painter;
            
            // Init Tabs
            previewerControl = new PreviewerControl(scene, this);
            previewerTab = new Tab(previewerControl, "Preview");

            //PropertiesControl propertiesControl = new PropertiesControl(scene, this);
            //propertiesTab = new Tab(propertiesControl, "Properties");
            segmentPropertiesControl = new PBR.Controls.SegmentPropertiesControl(scene, this);
            propertiesTab = new Tab(segmentPropertiesControl, "Paint Properties");

            viewerControl = new ViewerControl(scene, this);
            viewerTab = new Tab(viewerControl, "Viewer");

            //layersControl = new LayersControl(scene, this);
            //layersTab = new Tab(layersControl, "Layers");

            materialProperties = new PBR.Controls.MaterialProperties(scene);
            materialPropertiesTab = new Tab(materialProperties, "Render Properties");

            materialsPanel = new PBR.Controls.MaterialsPanel(scene);
            materialsPanelTab = new Tab(materialsPanel, "Styles");

            strokeProperties = new PBR.Controls.StrokeProperties(scene, this);
            strokePropertiesTab = new Tab(strokeProperties, "Stroke Properties");

            // Add Controls to MainForm
            rightTopTabControl.TabPages.Add(previewerTab);
            rightBottomTabControl.TabPages.Add(propertiesTab);
            rightBottomTabControl.TabPages.Add(materialPropertiesTab);
            rightBottomTabControl.TabPages.Add(strokePropertiesTab);
            centerTabControl.TabPages.Add(viewerTab);
            //leftTabControl.TabPages.Add(layersTab);
            leftTabControl.TabPages.Add(materialsPanelTab);

            scene.Renderer.Painter.SegmentImage();
            scene.Renderer.Painter.CompositeEdges();
        }

        public void Refresh()
        {
            previewerTab.Refresh();
            propertiesTab.Refresh();
            viewerTab.Refresh();
            //layersTab.Refresh();
        }

        /// <summary>
        /// Calls the newImage handlers for each component
        /// </summary>
        public void NewImage()
        {
            previewerControl.NewImage();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Contains all the information about the painting
        /// </summary>
        public Scene Scene
        {
            get
            {
                return scene;
            }
            set
            {
                scene = value;
            }
        }

        #endregion

        #region Event Handlers

        private void mViewerFormBtn_Click(object sender, EventArgs e)
        {
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        /// <summary>
        /// Render the current scene
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripRenderBtn_Click(object sender, EventArgs e)
        {
            UseWaitCursor = true;
            scene.Painting.Layers[0].PaintImage = new BitmapUnsafe(Path.Combine(kBasePath, "flower\\colorComposite.png"));
            scene.Painting.Layers[0].SpecResultImage = new BitmapUnsafe(Path.Combine(kBasePath, "flower\\spec.png"));
            scene.Painting.Layers[0].HeightImage = new BitmapUnsafe(Path.Combine(kBasePath, "flower\\heightComposite.png"));
            //mScene.Painting.Layers[0].ColorResult = new BitmapUnsafe(mScene.Painting.Layers);
            //mScene.Painting.Layers[0].SpecResult = new BitmapUnsafe(Path.Combine(kBasePath, "white_512.png"));
            //mScene.Painting.Layers[0].HeightResult = new BitmapUnsafe(Path.Combine(kBasePath, "test10\\height0Result.png"));
            scene.Renderer.Execute();
            scene.Painting.OutputImage.Bitmap.Save(Path.Combine(kBasePath, "flower\\output.png"));
            //mViewerForm.PictureBox.Image = scene.Painting.OutputImage.Bitmap;
            UseWaitCursor = false;
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            //UseWaitCursor = true;
            ////scene.Renderer.GenerateSobel();

            //AForge.Imaging.Filters.GaussianBlur gaussianBlur = new AForge.Imaging.Filters.GaussianBlur(15.0f);
            //scene.Painting.ActiveLayer.EdgesImage.Bitmap = gaussianBlur.Apply(scene.Painting.ActiveLayer.EdgesImage.Bitmap);
            //scene.Painting.ActiveLayer.EdgesImage.Bitmap.Save(Path.Combine(kBasePath, "flower\\edges1Blurred.png"));

            //scene.Renderer.FluxCapacitor();
            //scene.Painting.Layers[0].SpecResultImage = scene.Painting.Layers[0].SpecularImage;
            //scene.Painting.Layers[0].PaintImage.Bitmap.Save(Path.Combine(kBasePath, "flower\\color1Result.png"));
            //scene.Painting.Layers[0].HeightResultImage.Bitmap.Save(Path.Combine(kBasePath, "flower\\height1Result.png"));
            ////mVectorForm.PictureBox.Image = mScene.Painting.Layers[0].HeightResult.Bitmap;
            ////mVectorForm.Text = "Height";
            ////mViewerForm.Text = "Color";
            ////mVectorForm.Refresh();
            //UseWaitCursor = false;
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
        //    UseWaitCursor = true;
        //    //scene.Renderer.GenerateSobel();
        //    //scene.Renderer.GenerateVectorImage();
        //    scene.Painting.Layers[0].SpecResultImage = scene.Painting.Layers[0].SpecularImage;
        //    scene.Painting.Layers[0].PaintImage.Bitmap.Save(Path.Combine(kBasePath, "test11\\color0Result.png"));
        //    scene.Painting.Layers[0].HeightResultImage.Bitmap.Save(Path.Combine(kBasePath, "test11\\height0Result.png"));
        //    //mVectorForm.PictureBox.Image = mScene.Painting.Layers[0].HeightResult.Bitmap;
        //    //mVectorForm.Text = "Height";
        //    //mViewerForm.Text = "Color";
        //    //mVectorForm.Refresh();
        //    UseWaitCursor = false;
        }

        /// <summary>
        /// Main menu - Open Event Handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void mRenderBtn_Click(object sender, EventArgs e)
        {
        }

        private void mToolStripStatusLabel1_Click(object sender, EventArgs e)
        {

        }

        private void mToolStripStatusLabel1_TextChanged(object sender, EventArgs e)
        {

        }

        #endregion

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewProjectDialog newProjectDialog = new NewProjectDialog();

            if (newProjectDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            // open the color iamge
            scene.Painting.ActiveLayer.ColorImage.Dispose();
            scene.Painting.ActiveLayer.ColorImage = new BitmapUnsafe(newProjectDialog.colorFilename);

            // open the image
            scene.Painting.ActiveLayer.SegmentsImage.Dispose();
            //AForge.Imaging.Filters.GrayscaleBT709 grayscaleFilter = new AForge.Imaging.Filters.GrayscaleBT709();
            scene.Painting.ActiveLayer.SegmentsImage.Bitmap = new Bitmap(newProjectDialog.segmentFilename);

            // create a new image tier - contains the blurred color and edges images
            scene.Painting.ActiveLayer.ImageTier.Dispose();
            scene.Painting.ActiveLayer.ImageTier = new Tier(scene.Painting.ActiveLayer.ColorImage.Bitmap, scene.Painting.ActiveLayer.SegmentsImage.Bitmap);
            scene.Painting.ActiveLayer.PaintImage.Dispose();
            scene.Painting.ActiveLayer.PaintImage = new BitmapUnsafe("PaintImage", scene.Painting.ActiveLayer.ColorImage);

            scene.Painting.ActiveLayer.ImageTier.EdgesImages[0].Bitmap.Save(Path.Combine(kBasePath, "edge0.png"));
            scene.Painting.ActiveLayer.ImageTier.EdgesImages[1].Bitmap.Save(Path.Combine(kBasePath, "edge1.png"));
            scene.Painting.ActiveLayer.ImageTier.EdgesImages[2].Bitmap.Save(Path.Combine(kBasePath, "edge2.png"));
            scene.Painting.ActiveLayer.ImageTier.EdgesImages[3].Bitmap.Save(Path.Combine(kBasePath, "edge3.png"));

            // segment the image
            scene.Renderer.Painter.SegmentImage();

            // create a new vector image
            scene.Painting.ActiveLayer.VectorImage.Dispose();
            scene.Painting.ActiveLayer.VectorImage = new BitmapUnsafe("VectorImage", scene.Painting.ActiveLayer.ColorImage);

            // clear
            //scene.Painting.ActiveLayer.ObjectLabels = new int[scene.Painting.ActiveLayer.ColorImage.Width, scene.Painting.ActiveLayer.ColorImage.Height];
            scene.Painting.ActiveLayer.StrokeArray = new Stroke[scene.Painting.ActiveLayer.ColorImage.Width, scene.Painting.ActiveLayer.ColorImage.Height];

            // update the UI components
            NewImage();

            // change the sizes of the windows to fit the new image
            viewerControl.UpdateSizes();

            // compute the new vector field/brush strokes
            viewerControl.ComputeVectorField();

            // refresh all open windows
            Refresh();

            /* Old from before
             * 
             * SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.Title = "Save Project";
            saveFileDialog1.InitialDirectory = kDefaultPath;
            if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                scene.NewProject(Path.GetDirectoryName(saveFileDialog1.FileName),
                        Path.GetFileName(saveFileDialog1.FileName));
            }


            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Title = "Save Project";
            saveFileDialog.InitialDirectory = kDefaultPath;
            saveFileDialog.AddExtension = true;
            saveFileDialog.DefaultExt = "pbr";
            saveFileDialog.OverwritePrompt = true;

            if (saveFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                int i = 0;
            }*/




        }

        private void MainForm_Load(object sender, EventArgs e)
        {

        }

        private void colorTab_Click(object sender, EventArgs e)
        {

        }

        private void previewerTab_Click(object sender, EventArgs e)
        {

        }

        #region ColorTab


        #endregion

        public BindingSource PropertiesBindingSource
        {
            get { return propertiesBindingSource; }
            set { propertiesBindingSource = value; }
        }

        private void leftTabControl_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        #region ToolBar

        private void zoomInBtn_Click(object sender, EventArgs e)
        {
            scene.Zoom += 0.25f;
            viewerTab.Invalidate();
        }

        #endregion 

        private void zoomOutBtn_Click(object sender, EventArgs e)
        {
            scene.Zoom += 0.25f;
        }
    }
}